package org.example;

import java.sql.SQLOutput;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class testt4 {
    public static void main(String[] args) {
        //正则表达式  从左到右依次匹配
        //只能是a b c
        System.out.println("=============1");
        System.out.println("a".matches("[abc]"));
        System.out.println("b".matches("[abc]"));
        System.out.println("c".matches("[abc]"));
        System.out.println("d".matches("[abc]"));
        System.out.println("ab".matches("[abc]"));

        //不能出现a b c
        System.out.println("=============2");
        System.out.println("a".matches("[^abc]"));
        System.out.println("z".matches("[^abc]"));
        System.out.println("zz".matches("[^abc]"));
        System.out.println("zz".matches("[^abc][^abc]"));

        //a-z A-Z 0-9 包括头尾
        System.out.println("==============3");
        System.out.println("a".matches("[a-zA-Z0-9]"));
        System.out.println("z".matches("[a-zA-Z0-9]"));
        System.out.println("0".matches("[a-zA-Z0-9]"));

        //[a-d[m-p]] a到d 或 m到p
        System.out.println("==============4");
        System.out.println("a".matches("[a-d[m-p]]"));
        System.out.println("z".matches("[a-d[m-p]]"));
        //[a-d&&[m-p]] a到d 交集 m到p
        //[a-d&[m-p]] a-z & m-p
        System.out.println("==============5");
        System.out.println("z".matches("[a-d&&[m-p]]"));
        System.out.println("&".matches("[a-d&[m-p]]"));
        //[a-z&&[^bc]] a-z 和 不是b c 的交集
        System.out.println("a".matches("[a-z&&[^bc]]"));


        //预定义字符类
        //. 任意字符
        System.out.println("===============6");
        System.out.println("你a".matches(".."));
        System.out.println("a".matches("."));
        // \\d表示任意一个数字
        //两个\表示一个\
        System.out.println("===============7");
        System.out.println("a".matches("\\d"));
        System.out.println("12".matches("\\d\\d"));
        System.out.println("123".matches("\\d\\d\\d"));
        //\\D表示任意一个非数字
        System.out.println("===============8");
        System.out.println("a".matches("\\D"));
        System.out.println("1".matches("\\D"));
        // \\w表示任意一个单词字符  单词字符包括 字母 数字 下划线  [a-zA-Z0-9_]
        System.out.println("===============9");
        System.out.println("a".matches("\\w"));
        System.out.println("1".matches("\\w"));
        System.out.println("_".matches("\\w"));
        // \\W表示任意一个非单词字符
        System.out.println("===============10");
        System.out.println("a".matches("\\W"));
        System.out.println("1".matches("\\W"));
        System.out.println("你".matches("\\W"));//ture

        // \\w{num，}表示任意一个单词字符  单词字符包括 字母 数字 下划线  [a-zA-Z0-9_] 至少num个
        // \\w{num}表示任意一个单词字符  单词字符包括 字母 数字 下划线  [a-zA-Z0-9_] 恰好num个
        System.out.println("===============11");
        String str="1[3-9]\\d{9}";//1表示开头 3-9表示第二位  \\d{9}表示后面9位
        System.out.println("13333333333".matches(str));
        //座机号
        String str1="0\\d{2,3}-\\d{7,8}";
        System.out.println("13333333333".matches(str1));
        String str2="0\\d{2,3}-\\d{7,8}";
        System.out.println("13333333333".matches(str2));

        //右键点击第一插件any-rules  寻找相关正则表达式
        System.out.println("===============12");
        //忽略大小写
        String str3="a(?i)b";
        System.out.println("ab".matches(str3));
        System.out.println("Ab".matches(str3));
        System.out.println("aB".matches(str3));
        System.out.println("AB".matches(str3));


        String st="java自从95年问世以来，abbbbbbbbbaaaaa，经历了很多版本，目前企业中用的最多" +
                "的是Java8和JAva11，因为这两个是长期支持版本，下一个长期支持版本是JAVa17，" +
                "相信在未来不久JAVA17也会逐渐登上历史舞台";

        //method1(st);
        System.out.println("===============13");
        Pattern p=Pattern.compile("Java(?:\\d{0,2})");
       // Pattern p=Pattern.compile("Java\\d{0,2}");
        Matcher m=p.matcher(st);
        while(m.find()){
            String s=m.group();
            System.out.println(s);
        }

        System.out.println("===============14");
        //正向肯定预查
        //(?=exp) 匹配exp前面的位置
        //(?<=exp) 匹配exp后面的位置
        //(?!exp) 匹配后面跟的不是exp的位置
        //(?<!exp) 匹配前面不是exp的位置
        //注意：exp前面和后面的位置，不是exp的开始和结束位置

        //(?:8|11|17) 打印Java8 Java11 Java17

        //Pattern p1=Pattern.compile("Java(?=8|11|17)");
        Pattern p2=Pattern.compile("((?i)Java)(?=8|11|17)");
        //找到Java后面有8 11 17的子串，但是只打印Java，不打印后面的数字
        Matcher m2=p2.matcher(st);
        while(m2.find()){
            String s2=m2.group();
            System.out.println(s2);
        }

        System.out.println("===============15");
        Pattern p3=Pattern.compile("((?i)Java)(?!8|11|17)");
        Matcher m3=p3.matcher(st);
        while(m3.find()){
            String s3=m3.group();
            System.out.println(s3);
        }

        System.out.println("===============16");
        String st1="来黑马程序员学习java,座机电话是010-88888888,029-6666666,0571-7777777,0571-6666666,联系邮箱是" +
                "boniu@itcast.com,电话是18824409039,13122223333,15644445555，邮箱是2684162079qq.com" +
                "热线电话是400-618-9090";
        String regex="(0\\d{2,3}-?[1-9]\\d{4,9})" +
                "|(1[3-9]\\d{9})" +
                "|(\\w+@\\w+\\.[a-zA-Z]{2,3})" +
                "|(400-?\\d{3,4}-?\\d{4})";
        Pattern p1=Pattern.compile(regex);
        Matcher m1=p1.matcher(st1);
        while(m1.find()){
            String match=m1.group();
            System.out.println(match);
        }
        System.out.println("===============17");
        /*ab+:
        贪婪爬取：abbbbbbbb
        非：ab
        Java中，默认的是贪婪爬取
        如果我们想要非贪婪爬取，只需要在量词+ *的后面加上？即可
        */
        Pattern p4=Pattern.compile("ab+");
        Matcher m4=p4.matcher(st);
        while(m4.find()){
            String match=m4.group();
            System.out.println(match);
        }
        System.out.println("===============18");
        Pattern p5=Pattern.compile("ab+?");
        Matcher m5=p5.matcher(st);
        while(m5.find()){
            String match=m5.group();
            System.out.println(match);
        }
        System.out.println("===============19");
        String st2="小诗诗asdfg1234小丹丹asdfg1234小慧慧";
        //+表示至少一个  split切割字符串的时候，会把符合规则的子串作为切割点进行切割
        String []arr=st2.split("[\\w&&[^_]]+");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        //替换字符串
        String result=st2.replaceAll("[\\w&&[^_]]+","vs");
        System.out.println(result);

        System.out.println("===============20");
        // \\x  表示把第一组内容再来用一次
        //  "(.+).+\\1"  表示匹配任意字符，至少一个，然后再匹配任意字符，至少一个，然后再把第一组内容再来用一次
        String regex1="(.).+\\1";
        System.out.println("a123a".matches(regex1));
        System.out.println("&abc&".matches(regex1));
        System.out.println("a123b".matches(regex1));
        System.out.println("1231".matches(regex1));


        System.out.println("===============21");
        String regex2="((.)\\2*).+\\1";
        System.out.println("aaa123aaa".matches(regex2));
        System.out.println("abc123abc".matches(regex2));

        System.out.println("===============22");
        //$1 表示第一组内容
        //组号特点：以第一个左括号为基准，为第一组
        //捕获分组：正则内部使用 \\x ; 正则内部 $x  表示第x组内容
        //非捕获分组：正则内部使用 (?:)(?=)(?!) 分组之后仅仅把数组括起来，不参与分组
        String st3="我要学学编编编程程程";
        String result2=st3.replaceAll("(.)\\1+","$1");
        System.out.println(result2);






    }

    private static void method1(String st) {
        //Pattern 正则表达式的 编译 表示形式
        //Matcher 正则表达式的匹配器 按照正则表达式的规则去从头开始读取字符串，
        //在大窜中找到符合规则的子串。
        //find() 查找输入序列中与该模式匹配的下一个子序列
        //group() 返回由以前匹配操作所匹配的输入子序列
        //start() 返回以前匹配操作所匹配的输入子序列的开始处的索引
        //end() 返回以前匹配操作所匹配的输入子序列的结束处的索引

        //获取正则表达式对象
        Pattern p=Pattern.compile("Java\\d{0,2}");

        //获取文本匹配对象
        //m:文本匹配对象
        //str:大串
        //p:规则
        //m要在str中按照p规则从头开始匹配
        Matcher m=p.matcher(st);

        //寻找符合规则的子串
        //没有符合规则的子串返回false
        //有，返回true。在底层记录起始索引和结束索引+1
        boolean b=m.find();
        System.out.println(b);

        //方法底层会根据起始索引和结束索引+1截取子串
        //subString（开，末）包头不包尾
        String s1=m.group();
        System.out.println(s1);

        //第二次调用find的时候，会继续从上次结束的地方继续匹配
        //读到符合条件子串会继续返回ture
        //并把第二个子串其实和结束的索引+1记录下来
        b=m.find();

        //第二次调用group方法，会根据find方法记录索引再次截取子串
        String s2=m.group();
        System.out.println(s2);
    }
}
